package com.picshare.controller;

import com.picshare.config.ServerConfig;
import com.picshare.model.FileItem;
import com.picshare.model.PageResult;
import com.picshare.model.User;
import com.picshare.service.FileService;
import com.picshare.util.FileUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.stream.Collectors;

@Controller
public class FileController {
    
    @Autowired
    private FileService fileService;
    
    @Autowired
    private FileUtil fileUtil;
    
    
    @GetMapping("/")
    public String index(@RequestParam(defaultValue = "1") int page,
                       @RequestParam(defaultValue = "25") int size,
                       Model model, HttpSession session) {
        User user = (User) session.getAttribute("user");
        if (user == null) {
            return "redirect:/login";
        }
        
        PageResult<FileItem> pageResult = fileService.getFilesPage(page, size);
        model.addAttribute("pageResult", pageResult);
        model.addAttribute("user", user);
        model.addAttribute("fileUtil", fileUtil);
        return "index";
    }
    
    @GetMapping("/search")
    public String search(@RequestParam(required = false) String keyword,
                        @RequestParam(defaultValue = "1") int page,
                        @RequestParam(defaultValue = "25") int size,
                        Model model, HttpSession session) {
        User user = (User) session.getAttribute("user");
        
        // 获取服务器配置
        ServerConfig serverConfig = ServerConfig.getInstance();
        String serverUrl = serverConfig.getServerUrl();
        
        PageResult<FileItem> pageResult = fileService.searchFilesPage(keyword, page, size);
        model.addAttribute("pageResult", pageResult);
        model.addAttribute("keyword", keyword);
        model.addAttribute("user", user);
        model.addAttribute("fileUtil", fileUtil);
        model.addAttribute("serverUrl", serverUrl);
        return "index";
    }
    
    @PostMapping("/upload")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> upload(@RequestParam("file") MultipartFile file,
                                                     HttpSession session) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            User user = (User) session.getAttribute("user");
            if (user == null) {
                result.put("success", false);
                result.put("message", "请先登录");
                return ResponseEntity.ok(result);
            }
            
            if (file.isEmpty()) {
                result.put("success", false);
                result.put("message", "文件不能为空");
                return ResponseEntity.ok(result);
            }
            
            FileItem fileItem = fileService.uploadFile(file, user.getUsername());
            
            if (fileItem == null) {
                result.put("success", false);
                result.put("duplicate", true);
                result.put("message", "文件已存在");
            } else {
                result.put("success", true);
                result.put("message", "上传成功");
                result.put("file", fileItem);
            }
            
        } catch (IOException e) {
            result.put("success", false);
            result.put("message", "上传失败: " + e.getMessage());
        }
        
        return ResponseEntity.ok(result);
    }
    
    @PostMapping("/files/delete")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> deleteFile(@RequestParam String id) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            fileService.deleteFile(id);
            result.put("success", true);
            result.put("message", "删除成功");
        } catch (IOException e) {
            result.put("success", false);
            result.put("message", "删除失败: " + e.getMessage());
        }
        
        return ResponseEntity.ok(result);
    }
    
    @PostMapping("/files/batch-delete")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> batchDeleteFiles(@RequestParam String fileIds) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 解析文件ID列表
            List<String> fileIdList = Arrays.stream(fileIds.split(","))
                    .map(String::trim)
                    .filter(id -> !id.isEmpty())
                    .collect(Collectors.toList());
            
            if (fileIdList.isEmpty()) {
                result.put("success", false);
                result.put("message", "请选择要删除的文件");
                return ResponseEntity.ok(result);
            }
            
            // 批量删除文件
            int deletedCount = 0;
            List<String> failedFiles = new ArrayList<>();
            
            for (String fileId : fileIdList) {
                try {
                    fileService.deleteFile(fileId);
                    deletedCount++;
                } catch (IOException e) {
                    failedFiles.add(fileId);
                    System.err.println("删除文件失败: " + fileId + ", 错误: " + e.getMessage());
                }
            }
            
            if (deletedCount > 0) {
                result.put("success", true);
                result.put("deletedCount", deletedCount);
                result.put("message", "成功删除 " + deletedCount + " 个文件");
                
                if (!failedFiles.isEmpty()) {
                    result.put("failedCount", failedFiles.size());
                    result.put("failedFiles", failedFiles);
                    result.put("warning", "有 " + failedFiles.size() + " 个文件删除失败");
                }
            } else {
                result.put("success", false);
                result.put("message", "没有文件被删除");
            }
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "批量删除失败: " + e.getMessage());
        }
        
        return ResponseEntity.ok(result);
    }
    
    @PostMapping("/files/rename")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> renameFile(@RequestParam String id,
                                                          @RequestParam String newName) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            FileItem fileItem = fileService.renameFile(id, newName);
            if (fileItem != null) {
                result.put("success", true);
                result.put("message", "重命名成功");
                result.put("file", fileItem);
            } else {
                result.put("success", false);
                result.put("message", "文件不存在");
            }
        } catch (IOException e) {
            result.put("success", false);
            result.put("message", "重命名失败: " + e.getMessage());
        }
        
        return ResponseEntity.ok(result);
    }
    
    @GetMapping("/files/{fileId}/info")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> getFileInfo(@PathVariable String fileId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            FileItem fileItem = fileService.getFileById(fileId);
            if (fileItem != null) {
                result.put("success", true);
                result.put("id", fileItem.getId());
                result.put("originalName", fileItem.getOriginalName());
                result.put("fileName", fileItem.getFileName());
                result.put("size", fileItem.getSize());
                result.put("type", fileItem.getType());
                result.put("image", fileItem.isImage());
            } else {
                result.put("success", false);
                result.put("message", "文件不存在");
            }
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取文件信息失败: " + e.getMessage());
        }
        
        return ResponseEntity.ok(result);
    }
    
    @GetMapping("/files/view/{fileId}")
    public ResponseEntity<byte[]> viewFile(@PathVariable String fileId) {
        FileItem fileItem = fileService.getFileById(fileId);
        if (fileItem == null) {
            return ResponseEntity.notFound().build();
        }
        
        try {
            Path filePath = Paths.get("./albums", fileItem.getFileName());
            if (!Files.exists(filePath)) {
                return ResponseEntity.notFound().build();
            }
            
            byte[] fileBytes = Files.readAllBytes(filePath);
            
            // 根据文件类型设置Content-Type
            String contentType = getContentType(fileItem.getType());
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType(contentType));
            headers.setContentLength(fileBytes.length);
            
            return ResponseEntity.ok()
                    .headers(headers)
                    .body(fileBytes);
                    
        } catch (IOException e) {
            return ResponseEntity.internalServerError().build();
        }
    }
    
    private String getContentType(String fileExtension) {
        switch (fileExtension.toLowerCase()) {
            case "jpg":
            case "jpeg":
                return "image/jpeg";
            case "png":
                return "image/png";
            case "gif":
                return "image/gif";
            case "webp":
                return "image/webp";
            case "bmp":
                return "image/bmp";
            case "tiff":
                return "image/tiff";
            case "svg":
                return "image/svg+xml";
            case "pdf":
                return "application/pdf";
            case "txt":
                return "text/plain";
            case "doc":
            case "docx":
                return "application/msword";
            case "xls":
            case "xlsx":
                return "application/vnd.ms-excel";
            case "ppt":
            case "pptx":
                return "application/vnd.ms-powerpoint";
            default:
                return "application/octet-stream";
        }
    }
}